#!/usr/bin/env python3
#coding=utf-8
#請執行本程式以啟動lonote

import sys
import os
import os.path
import functools
import argparse
import configparser
import urllib.request as UR
# import shelve

@functools.lru_cache()
def execDir():
    '''執行檔所在資料夾'''
    return os.path.abspath(os.path.dirname(sys.argv[0]))
    # return os.path.dirname(os.path.realpath(__file__))

# source pack library change
def lib_path():
    # 原碼包中 libdir 位置
    lib_dir = os.path.join(execDir(), 'lonotelib')
    if not os.path.isdir(lib_dir):
        # linux 下有時程式會被安裝到這裡，故增加匯入路徑
        lib_dir = '/usr/lib/python3/dist-packages/lonotelib'
    return lib_dir


sys.path[0] = lib_path()


import civa.futil
import lonote.loserver
import lonote.imcv
import lonote.info
import lonote.translate

# 嘗試使用原碼包的 locale 路徑
src_locale_dir = os.path.join(execDir(), 'locale')
if os.path.isdir(src_locale_dir):
    lonote.translate.LOCALE_DIR = src_locale_dir

# 取得翻譯函式
g = lonote.translate.get_server_gettext_func()


@functools.lru_cache()
def config_path():
    '''取得設定路徑'''
    cfgpath = os.path.join(execDir(), 'config')
    if os.path.isdir(cfgpath): # 使用資料夾路徑
        return cfgpath
    else: # 使用程式設定路徑
        userdir = civa.futil.userdir()
        cfgpath = os.path.join(userdir, '.config')
        return cfgpath

@functools.lru_cache()
def server_path():
    '''取得 server 路徑'''
    serpath = os.path.join(execDir(), 'server')
    if os.path.isdir(serpath): # 使用資料夾路徑
        return serpath
    else: # 使用程式設定路徑
        serpath = os.path.join(
                os.path.dirname(execDir()),
                'share',
                'lonote',
                'server')
        return serpath

cfgpth = config_path()
# setting_file = os.path.join(cfgpth, 'lonote', 'loset')
# se = shelve.open(setting_file) # 後面要記得 close
# BOOKS_DIR = se.get('books_dir')
# if BOOKS_DIR is None:
#     BOOKS_DIR = os.path.join(cfgpth, 'lonote', 'book')
# INDEX_DIR = se.get('index_dir')
# if INDEX_DIR is None:
#     INDEX_DIR = os.path.join(cfgpth, 'lonote', 'index')
BOOKS_DIR = os.path.join(cfgpth, 'lonote', 'book')
INDEX_DIR = os.path.join(cfgpth, 'lonote', 'index')

USER_STATIC_DIR = os.path.join(cfgpth, 'lonote', 'static')
LOGGING_FILE = os.path.join(cfgpth, 'lonote', 'logging.txt')

serpth = server_path()
TEMPLATE_DIR = os.path.join(serpth, 'template')
STATIC_DIR = os.path.join(serpth, 'static')

# cfgdir 預創建
lonotecfg_dir = os.path.join(cfgpth, 'lonote')
try:
    os.makedirs(lonotecfg_dir, exist_ok = True)
except:
    pass

# 預設 browser 從檔案中讀取，讀取失敗表示為 default
cfg_file = os.path.join(cfgpth, 'lonote', 'lonote.cfg')
cfg = configparser.ConfigParser()

if os.path.isfile(cfg_file):
    cfg.read(cfg_file);
    preset_browsers = cfg.get('DEFAULT','default_browsers').replace(',', ' ').split()
else:
    cfg['DEFAULT'] = {'default_browsers': ''}
    with open(cfg_file, mode = "w", encoding = "utf8") as f:
        cfg.write(f)
    # load
    preset_browsers = cfg.get('DEFAULT','default_browsers').replace(',', ' ').split()

# ================ command line args process ========================

description = g('''LoNote is a personal note-taking software base on web page and python3.''')

parser = argparse.ArgumentParser(
        description = description,
        #formatter_class = argparse.ArgumentDefaultsHelpFormatter
        )
parser.add_argument('browser',
        nargs = '*',
        default = preset_browsers,
        help = g('A browser you want to open.'))
parser.add_argument('-d', '--debug',
        dest = 'debug',
        action = 'store_true',
        help = g('Use debug mode'))
parser.add_argument('-n','--no-browser',
        dest = 'nobrowser',
        action = 'store_true',
        help = g('Do not auto-open any browser.'))
parser.add_argument('-p', '--port',
        dest = 'port',
        type = int,
        default = 10204,
        help = g('Set the server port.'))
parser.add_argument('--remote',
        dest = 'remote',
        default = False,
        action = 'store_true',
        help = g('Let other computer can connect to this server. (be careful! LoNote NOT implement any auth (yet). So everybody can edit your data!)'))
parser.add_argument('--version',
        dest = 'version',
        action = 'store_true',
        help = g('Show version and exit.'))
parser.add_argument('--stop',
        dest = 'stop',
        default = False,
        action = 'store_true',
        help = g('Stop server on target port.'))
parser.add_argument('--restart',
        dest = 'restart',
        default = False,
        action = 'store_true',
        help = g('Restart server on target port.'))
parser.add_argument('--dir-book',
        dest = 'booksdir',
        default = BOOKS_DIR,
        help = g('All notebooks must be placed in here.'))
parser.add_argument('--dir-index',
        dest = 'indexdir',
        default = INDEX_DIR,
        help = g('All search index will be stored in here.'))
parser.add_argument('--convert',
        dest = 'convert',
        nargs = 1,
        help = g('Convert a old notebook (LoNote version >= 1.8 and <=1.8.7) To a LoNote 2.X format, and exit.'))
parser.add_argument('--convert-keep-history',
        dest = 'convert_keep_history',
        action = 'store_true',
        help = g('Keep all history when --convert be used.'))

args = parser.parse_args()

# ============== Version =======================

if args.version:
    print(lonote.info.version)
    sys.exit(0)

# ============== 順便檢查／確保資料夾有正確初始化 ====================

if not os.path.isdir(args.booksdir):
    os.makedirs(args.booksdir)
if not os.path.isdir(args.indexdir):
    os.makedirs(args.indexdir)

# ========================== Convert =================================

if args.convert:
    fname = os.path.basename(args.convert[0])
    fuzzy_dst = os.path.join(args.booksdir, fname)
    dst = None
    try:
        dst = lonote.imcv.from_18X_getdst_fpath(fuzzy_dst)
    except lonote.imcv.IMCVError as e:
        print(e)
        ans = input('Replace? (y/N): ')
        if ans.lower() == 'y':
            dst = lonote.imcv.from_18X_getdst_fpath(fuzzy_dst, delete_target = True)
        else:
            print('cancel')
            sys.exit(0);

    if dst:
        lonote.imcv.from_18X(src = args.convert[0], dst = dst,
                keep_history = args.convert_keep_history)
    os._exit(0);

# =========================== Browser setting========================

browser_list = []

for browser in args.browser:
    browser_list.append(browser)

if args.nobrowser:
    browser_list = None

# =========================== Server Stop ==========================

def stop_server():
    '''測試並關閉目標 port 上正在運作的 LoNote 伺服器'''
    test_target = 'http://localhost:{}'.format(args.port)
    shutdown_target = 'http://localhost:{}/config?cmd=shutdown'.format(args.port)
    try:
        UR.urlopen(test_target)
        try:
            UR.urlopen(shutdown_target, data = b'')
            print('Shutdown failed, Server already run on {} port.'.format(args.port))
        except:
            print('Shutdown Success on {} port.'.format(args.port))
    except:
        print('No LoNote Server run on {} port.'.format(args.port))

if args.stop or args.restart:
    stop_server()
    if not args.restart:
        sys.exit()


# =========================== Start Server ==========================

lonote.loserver.start_server(
        books_dir = args.booksdir,
        index_dir = args.indexdir,
        template_dir = TEMPLATE_DIR,
        user_static_dir = USER_STATIC_DIR,
        static_dir = STATIC_DIR,
        debug = args.debug,
        browser_list = browser_list,
        logging_file = LOGGING_FILE,
        local = not args.remote,
        port = args.port)
